package com.gm.triad.app.countdown;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RemoteViews;

public abstract class AbstractConfigureActivity extends Activity {
	Button mApplyButton;
	EditText mDateField;
	EditText mEventNameField;
	
	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
	
	protected static final String TAG = AbstractConfigureActivity.class.getSimpleName();
	
	public abstract boolean isSmallWidget();
	
	@Override
	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		
        // Set the result to CANCELED.  This will cause the widget host to cancel
        // out of the widget placement if they press the back button.
        setResult(RESULT_CANCELED);

        setContentView(R.layout.configure_layout);

        mApplyButton = (Button)findViewById(R.id.applyButton);
        mApplyButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (validateAndSavePref()) {
					updateWidget(v.getContext(), mAppWidgetId, isSmallWidget());
					
					Intent resultValue = new Intent();
					resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
					setResult(RESULT_OK, resultValue);
					finish();

				}
			}
		});
        
        mDateField = (EditText) findViewById(R.id.dateField);
        mEventNameField = (EditText) findViewById(R.id.eventNameField);
        
        
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        if (extras != null) {
            mAppWidgetId = extras.getInt(
                    AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        }

        // If they gave us an intent without the widget id, just bail.
        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
            finish();
        }
        
        
	    if (mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
	    	// Get the shared preferences.
	    	SharedPreferences prefs = prefs(this);
	    	String dateStr = prefs.getString("date-" + mAppWidgetId, null);
	    	String eventNameStr = prefs.getString("eventName-" + mAppWidgetId, null);
	    	
    		mDateField.getEditableText().clear();
	    	if (dateStr != null) {
	    		mDateField.getEditableText().append(dateStr);
	    	}

	    	mEventNameField.getEditableText().clear();
	    	if (eventNameStr != null) {
	    		mEventNameField.getEditableText().append(eventNameStr);
	    	}
	    }

	}
	
	protected static String getEventNameForDisplay(Context context, int widgetId) {
		SharedPreferences prefs = prefs(context);
		return prefs.getString("eventName-" + widgetId, "<empty>");
	}

	protected static final long MS_IN_A_WEEK = 604800 * 1000;
	protected static final long MS_IN_A_DAY = 86400 * 1000;
	protected static final String EMPTY = "<empty>";
	
	protected static String getCountdownForDisplay(Context context, int widgetId) {
		SharedPreferences prefs = prefs(context);
		
		String dateStr = prefs.getString("date-" + widgetId, EMPTY);
		String result = EMPTY;
		if (!dateStr.equals(EMPTY)) {
			try {
				Date d = DATE_FORMAT.parse(dateStr);

				long thenMS = d.getTime();
				long nowMS = System.currentTimeMillis();

				// Already occurred
				if (thenMS < nowMS) {
					result = "We have arrived!";
				}
				else {
					long diffMS = thenMS - nowMS;
					long numWeeks = (long)Math.ceil(((double)diffMS) / ((double)MS_IN_A_WEEK));
					long numDays = (long)Math.ceil(((double)diffMS) / ((double)MS_IN_A_DAY));
					if (numDays < 7) {
						result = "" + numDays + " day";
						if (numDays > 1) result += "s"; // plural!
					}
					else {
						result = "" + numWeeks + " week";
						if (numWeeks > 1) result += "s"; // plural!
					}
				}
			}
			catch (Exception ex) {
				Log.e(TAG, "Error parsing stored date", ex);
			}
		}
		
		
		return result;
	}
	
	public static void updateWidget(Context context, int widgetId, boolean smallLayout) {
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        // Create an Intent to launch the configuration activity.
        Intent intent = new Intent(context, smallLayout?ConfigureActivitySmall.class:ConfigureActivityLarge.class);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);  // Identifies the particular widget...
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // Make the pending intent unique...
        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
        
        int whichLayout = smallLayout?R.layout.appwidget_provider_small:R.layout.appwidget_provider_large;
        
		RemoteViews views = new RemoteViews(context.getPackageName(), whichLayout);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.countdownField, pendingIntent);        	
        if (!smallLayout) {
        	views.setOnClickPendingIntent(R.id.gmImage, pendingIntent);
        	views.setOnClickPendingIntent(R.id.projectNameField, pendingIntent);
        }
        views.setCharSequence(R.id.projectNameField, "setText", getEventNameForDisplay(context, widgetId));

        views.setCharSequence(R.id.countdownField, "setText", getCountdownForDisplay(context, widgetId));
        
		appWidgetManager.updateAppWidget(widgetId, views);
	}

	
	protected static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("M/d/yyyy");

	protected static SharedPreferences prefs(Context context) {
		return context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
	}
	
	protected boolean validateAndSavePref() {
		// Check that the date field is populated.
		String dateStr = mDateField.getEditableText().toString();
		Date d = null;
		try {
			d = DATE_FORMAT.parse(dateStr);
			if (d == null) throw new java.text.ParseException("Date format does not appear to be valid", 0);
		} catch (ParseException e) {
			e.printStackTrace();
			alertError("End Date","Must be formatted as MM/DD/YYYY");
			mDateField.requestFocus();
			return false;
		}
		
		// Check that the event name field is populated.
		String eventStr = mEventNameField.getEditableText().toString();
		if (eventStr == null || eventStr.trim().length() == 0) {
			alertError("Event Name", "Event Name must be entered");
			mEventNameField.requestFocus();
			return false;
		}
		
		// Store preferences.
		SharedPreferences sp = prefs(this);
		
		Editor editor = sp.edit();
		editor.putString("date-" + mAppWidgetId, dateStr);
		editor.putString("eventName-" + mAppWidgetId, eventStr);
		editor.commit();
		
		return true;
	}
	
	protected void alertError(String title, String msg) {
		AlertDialog.Builder b = new AlertDialog.Builder(this);
		if (title != null && title.length() > 0) b.setTitle(title);
		b.setCancelable(false).setMessage(msg);
		b.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		AlertDialog dialog = b.create();
		dialog.show();

	}
	
}
